var DotoPage = {
	
	loadTasks: function () {
		var jsm = {};
		Components.utils.import("resource://doto/modules/services.js", jsm);
		var tasks = jsm.DotoManager.getTasks();
		for (var i = 0; i < tasks.length; ++i) {
			var task = tasks[i];
			var text = '<div class="task" id="' + task.id + '">';
			var now = new Date();
			if (task.due.getTime() != 0 && task.due.getTime() <= now.getTime()) {
				text += " <em><b>" + task.title + "</b></em> ";
			} else {
				text += " " + task.title + " ";
			}
			if (task.due.getTime() != 0) {
				if (task.due.getTime() < now.getTime()) {
					text += '&nbsp;&nbsp;<span class="due-span"><b>Doomed~~</b></span>';
				} else {
					text += '&nbsp;&nbsp;<span class="due-span">' + DotoPage.formatTime(task.due) + '</span>';
				}
			}
			text += "</div>";
			$(text).appendTo("#content");
		}		
		
		var completedTasks = jsm.DotoManager.getCompletedTasks();
		var text = "<ul>";
		for (var i = 0; i < completedTasks.length && i < 25; ++i) {
			text += "<li>" + completedTasks[i].title + "</li>";
		}
		text += "</ul>";
		$(text).appendTo("#sidebar");
		
		$("#versionNumber").text(jsm.DotoManager.getVersionNumber());
		
		// runTimeTest();
	},
	
	formatTime: function (t) {
		var now = new Date();
		var text = "";
		if (t.getFullYear() === now.getFullYear() && t.getMonth() === now.getMonth() 
				&& t.getDate() === now.getDate()) {
			if (t.getHours() === 23 && t.getMinutes() === 59 && t.getSeconds() === 59) {
				text = "Today";
			} else {
				text = "";
				if (t.getHours() < 10) { text += "0"; }
				text += t.getHours() + ":";
				if (t.getMinutes() < 10) {text += "0"; }
				text += t.getMinutes();
			}
		} else {
			var diff = t.getTime() - now.getTime();
			if (diff < 0 ) {
				text = "Doomed~~";
			} else if (diff < 0.001) {
				text = "Right NOW";
			} else {
				var days = Math.floor(diff / (24 * 60 * 60 * 1000));
				if (now.getDay() + days >= 7) {
					if (days <= 20) {
						text = days + " days left";
					} else {
						text = t.getFullYear() + "-";
						if (t.getMonth() < 10) text += "0";
						text += t.getMonth() + "-";
						if (t.getDate() < 10) text += "0";
						text += t.getDate();
					}
				} else {
					var dayNames = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
					text = dayNames[t.getDay()];
				}
			}
		}
		
		return text; 
	},

	deleteTask: function(id) {
		var jsm = {};
		Components.utils.import("resource://doto/modules/services.js", jsm);
		jsm.DotoManager.deleteTask(id);
		window.location.reload(true);
	},
		
	completeTask: function(id) {
		var jsm = {};
		Components.utils.import("resource://doto/modules/services.js", jsm);
		jsm.DotoManager.completeTask(id);
		window.location.reload(true);
	},
	
	postponeTask: function(id) {
		var jsm = {};
		Components.utils.import("resource://doto/modules/services.js", jsm);
		jsm.DotoManager.postponeTask(id);
		window.location.reload(true);
	},
	
	checkInputDevice: function () {
		var value = $.trim($("#inputDevice").val());
		var testDiv = document.createElement("div");
		var test = document.createTextNode(value);
		testDiv.appendChild(test);
		value = testDiv.innerHTML;
		if (value) {
			var jsm = {};
			Components.utils.import("resource://doto/modules/services.js", jsm);
			// Need to extract due time from value
			jsm.DotoManager.addTask(value, TimeExtractor.extractTime(value));
			window.location.reload(true);
		}
		$("#inputDevice").val('');
	},

	inputKeyDown: function (e) {
		var key = e.keyCode;
		if (key == 13) {
			DotoPage.checkInputDevice();
		}
	},
	
	initPage: function () {
		$("#inputDevice").focus();
		$("#inputDevice").keydown(DotoPage.inputKeyDown);
		DotoPage.loadTasks();
		$("div.task").each(function(each) {
			$(this).hover(
				function() {
					$(this).addClass("hover");
					var id = this.id;
					var text = '<span class="actions">&nbsp;&nbsp;&nbsp;';
					text += '&nbsp;<a class="task-complete" href="javascript:void(0)" title="Complete this task" onclick="DotoPage.completeTask(' + id + ')">Complete</a>';
					text += '&nbsp;<a class="task-postpone" href="javascript:void(0)" title="Postpone or Due Today this task" onclick="DotoPage.postponeTask(' + id + ')">Postpone</a>';
					text += '&nbsp;<a class="task-delete"   href="javascript:void(0)" title="Delete this task" onclick="DotoPage.deleteTask(' + id + ')">Delete</a>';
					text += '</span>';
					$(this).append($(text));
				},
				function() {
					$(this).removeClass("hover");
					$(this).find("span:last").remove();					
				}
			)
		});		
	},
};

$(window).ready(DotoPage.initPage);

var TimeExtractor = {
	timeRxs: [
		/([1-9]|1[0-2])(:[0-5][0-9])?(\s)?(a|p)m/i,
		/([0-9]|[0-1][0-9]|2[0-3]):([0-5][0-9])/i
	],
	
	dateRxs: [
		/(\d{4}-)?(\d{2}|\d{1})-(\d{2}|\d{1})/i,
		/(next )?(mon|tue|wed|thur|fri|sat|sun)/i,
		/today|tomorrow|今天|明天/i,
		/(下|下个)?(星期|周)(一|二|三|四|五|六|七|天|日)/i
	],
	
	extractTime: function(text) {
		var due = new Date(0);
		if (this.dateRxs[0].test(text)) {
			// test on 2009-01-01
			var matches = this.dateRxs[0].exec(text);
			if (matches[1]) {
				due.setYear(parseInt(matches[1].substr(0, 4)));
			} else {
				due.setYear(new Date().getFullYear());
			}
			due.setMonth(parseInt(matches[2]) - 1);
			due.setDate(parseInt(matches[3]));
			due.setHours(23);
			due.setMinutes(59);
			due.setSeconds(59);
		} else if (this.dateRxs[1].test(text)) {
			// test on days of week like monday or next monday and also support in Chinese
			var matches = this.dateRxs[1].exec(text);
			var dueday = 0;
			switch(matches[2].toLowerCase()) {
				case 'sun': dueday = 0; break;
				case 'mon': dueday = 1; break;
				case 'tue': dueday = 2; break;
				case 'wed': dueday = 3; break;
				case 'thur': dueday = 4; break;
				case 'fri': dueday = 5; break;
				case 'sat': dueday = 6; break;
			}
			if (matches[1]) {
				dueday += 7;
			}
			due = new Date();
			if (dueday < due.getDay()) {
				dueday += 7;
			}
			dueday -= due.getDay();
			due.setTime(due.getTime() + dueday * 24 * 60 * 60 * 1000);
			due.setHours(23);
			due.setMinutes(59);
			due.setSeconds(59);
		} else if (this.dateRxs[2].test(text)) {
			// test on today
			var matches = this.dateRxs[2].exec(text);
			if (matches[0] == "today" || matches[0] == "今天") {
				due = new Date();
				due.setHours(23);
				due.setMinutes(59);
				due.setSeconds(59);
			} else {
				due = new Date();
				due.setDate(due.getDate() + 1);
				due.setHours(23);
				due.setMinutes(59);
				due.setSeconds(59);
			}
		} else if (this.dateRxs[3].test(text)) {
			// test on days of week like monday or next monday and also support in Chinese
			var matches = this.dateRxs[3].exec(text);
			var dueday = 0;
			switch(matches[3]) {
				case '七': dueday = 0; break;
				case '日': dueday = 0; break;
				case '天': dueday = 0; break;
				case '一': dueday = 1; break;
				case '二': dueday = 2; break;
				case '三': dueday = 3; break;
				case '四': dueday = 4; break;
				case '五': dueday = 5; break;
				case '六': dueday = 6; break;
			}
			if (matches[1]) {
				dueday += 7;
			}
			due = new Date();
			if (dueday < due.getDay()) {
				dueday += 7;
			}
			dueday -= due.getDay();
			due.setTime(due.getTime() + dueday * 24 * 60 * 60 * 1000);
			due.setHours(23);
			due.setMinutes(59);
			due.setSeconds(59);
		}
		
		if (this.timeRxs[1].test(text)) {
			var matches = this.timeRxs[1].exec(text);
			if (due.getTime() === 0) {
				due = new Date();
			}
			due.setHours(parseInt(matches[1]));
			due.setMinutes(parseInt(matches[2]));
			due.setSeconds(0);
		} else if (this.timeRxs[0].test(text)) {
			var matches = this.timeRxs[0].exec(text);
			if (due.getTime() == 0) {
				due = new Date();
			}
			if (matches[4].toLowerCase() === 'a') {
				due.setHours(parseInt(matches[1]));
			} else {
				due.setHours(parseInt(matches[1]) + 12);
			}
			if (matches[2]) {
				due.setMinutes(parseInt(matches[2].substr(1, 2)));
			} else {
				due.setMinutes(0);
			}
			due.setSeconds(0);
		}
		return due;
	}, 
};